#include "rasterizer.h"
#include <SDL_image.h>
#include <SDL_endian.h>
#include <stdio.h>

RRPrimitive prim;
RRRasterizer rast;

SDL_Surface *screen = NULL;
SDL_Surface *backscreen = NULL;
SDL_Surface *background_image = NULL;

void Update(void)
{
  /* here to code processes to update the state */
}

void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B)
{
  static int w = 0;
  prim.rrBegin(RR_POLYGON);
  prim.rrSetVert(320, 100);
  prim.rrSetVert(500, 180);
  prim.rrSetVert(500, 320);
  prim.rrSetVert(320, 400);
  prim.rrSetVert(140, 320);
  prim.rrSetVert(140, 180);
  //prim.rrSetVert(rand() % 640, rand() % 480);
  prim.rrEnd();

  rast.rrSetPrim(prim);
  rast.rrRast();
  w++;

  Uint32 color = SDL_MapRGB(screen->format, R, G, B);

  if(SDL_MUSTLOCK(screen)) {
    if(SDL_LockSurface(screen) < 0) {
      return;
    }
  }

  int x, y;

  for(x=0; x<640; x++)
    for(y=0; y<480; y++) {
      Uint32 *bufp;
      bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
      *bufp = color;
    }
  
  int pnum;
  pnum = rast.rrGetPointsNum();
  for(int i=0; i<pnum; i++) {
    RRPoint point;
    point = rast.rrGetPoint(i);
    color = SDL_MapRGB(screen->format, 0x00, 0, 0x60);
    Uint32 *bufp;
    bufp = (Uint32 *)screen->pixels + point.y * screen->pitch/4 + point.x;
    *bufp = color;
  }

  if(SDL_MUSTLOCK(screen)) {
    SDL_UnlockSurface(screen);
  }
  // SDL_UpdateRect(screen, x, y, 1, 1);
} 

void Draw(void)
{
  /* SDL_BlitSurface(background_image, NULL, screen, NULL); */

  static int blue = 1;
  static bool up = true;

  /* here to code drawing processes  */
  if(blue == 255) up = false;
  else if(blue == 0) up = true;
  DrawPixel(backscreen, 255 - (blue - 127) * (blue - 128)/64, 255 - blue, blue);
  if(up == true) blue += 1;
  else blue -= 1;

  // update screen
  SDL_BlitSurface(backscreen, NULL, screen, NULL);
  SDL_Flip(screen);

  // SDL_UpdateRect(backscreen, 0, 0, 0, 0);
}

int Initialize(void)
{
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
    fprintf(stderr, "failed to initialize SDL: %s\n", SDL_GetError());
    return -1;
  }

  SDL_WM_SetCaption("My SDL Sample", NULL);

  screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);

  backscreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

  if(screen == NULL) {
    fprintf(stderr, "failed to initialize the screen: %s\n", SDL_GetError());
    SDL_Quit();
    return -1;
  }

  return 0;
}

void MainLoop(void)
{
  SDL_Event event;
  double next_frame = SDL_GetTicks();
  double wait = 1000.0 / 60;

  for(;;) {
    /* deal with all events */
    while(SDL_PollEvent(&event)) {
      if((event.type == SDL_QUIT) || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE))
	return;
    }
    if(SDL_GetTicks() >= next_frame) {
      Update();
      if(SDL_GetTicks() < next_frame + wait)
	Draw();
      next_frame += wait;
      SDL_Delay(0);
    }
  }
}

void Finalize(void)
{
  /* here to free images and sounds */
  // SDL_FreeSurface(background_image);

  SDL_Quit();
}

int main(int argc, char *argv[])
{  
  if(Initialize() < 0)
    return -1;

  // printf("%d\n", screen->pitch);

  MainLoop();

  Finalize();

  return 0;
}

